package com.shoprh.demo.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.alibaba.fastjson.JSONObject;
import com.shoprh.system.service.IDeptService;
import com.shoprh.system.service.IMenuService;
import com.shoprh.system.service.IRoleService;
import com.shoprh.system.service.IUserService;
import com.shoprh.common.core.domain.R;
import com.shoprh.common.utils.DateUtils;
import com.shoprh.common.utils.RandomUtil;
import com.shoprh.common.utils.StringUtils;
import com.shoprh.system.domain.Dept;
import com.shoprh.system.domain.Role;
import com.shoprh.system.domain.User;
import com.shoprh.system.log.publish.PublishFactory;
import com.shoprh.system.util.PasswordUtils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.wf.jwtp.annotation.Ignore;
import org.wf.jwtp.provider.Token;
import org.wf.jwtp.provider.TokenStore;
import org.wf.jwtp.util.TokenUtil;

import java.util.List;
import java.util.Map;

/**
 * 微信小程序用户接口
 */
@Slf4j
@RestController
@RequestMapping("/api/wx_auth")
public class WxMaUserController {

    @Autowired
    private WxMaService wxMaService;
    @Autowired
    private TokenStore   tokenStore;
    @Autowired
    private IUserService userService;
    @Autowired
    private IMenuService menuService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IDeptService deptService;

    /**
     * 获取用户信息接口
     */
    @PostMapping("/register")
    public R register(@RequestBody JSONObject inData) {
        try {
            String code = inData.getString("code");
            String signature = inData.getString("signature");
            String rawData = inData.getString("rawData");
            String encryptedData = inData.getString("encryptedData");
            String iv = inData.getString("iv");

            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            String openId = session.getOpenid();
            // 检查是否是否存在
            User user = userService.selectUserByOpenid(openId);
            // 不存在则注册
            if (user == null) {
                String sessionKey = session.getSessionKey();
                // 用户信息校验
                if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
                    return R.error("获取用户信息接口出错");
                }
                // 解密用户信息
                WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
                // 设置默认信息
                user = new User();
                user.setUsername(RandomUtil.randomInt(6));
                user.setNickname(userInfo.getNickName());
                user.setMobile(RandomUtil.randomInt(11));
                user.setGender(userInfo.getGender());
                user.setAvatar(userInfo.getAvatarUrl());
                user.setCreateBy(userInfo.getNickName());
                user.setCreateTime(DateUtils.getNowDate());
                user.setSalt(RandomUtil.randomStr(6));
                user.setOpenid(openId);
                user.setPassword(PasswordUtils.encryptPassword(user.getUsername(), "admin123", user.getSalt()));

                //默认角色
                Role defaultRole = roleService.findDefault();
                if (StringUtils.isNull(defaultRole)) {
                    return R.error("默认角色未设置，请联系管理员!");
                }
                List<Long> roleIds = Lists.newArrayList();
                roleIds.add(defaultRole.getId());
                user.setRoleIds(roleIds);

                // 默认部门
                Dept defaultDept = deptService.findDefault();
                if (StringUtils.isNull(defaultDept)) {
                    return R.error("默认部门未设置，请联系管理员!");
                }
                user.setDeptId(defaultDept.getId());

                userService.insertUser(user);
            }
            // 签发token
            Long userId = user.getId();
            Token token = tokenStore.createNewToken(userId.toString(), menuService.selectPermsStrArray(userId), roleService.selectRoleStrArray(userId));
            Map<String, Object> map = Maps.newHashMap();
            map.put("userId", userId);
            map.put("token", token.getAccessToken());
            map.put("expire", TokenUtil.DEFAULT_EXPIRE);
            // 登记在线信息
            PublishFactory.recordUserOnlineInfo(user, token.getAccessToken());
            return R.ok(map);
        } catch (Exception e) {
            log.error("调用微信服务器出现异常", e);
            return R.error("获取微信用户数据失败");
        }
    }

    /**
     *
     * 获取用户信息接口
     *
     */
    @Ignore
    @GetMapping("/getUserInfo")
    public R getUserInfo(){

        return R.ok("userInfo");
    }


    /**
     * 获取用户绑定手机号信息
     */
    @PostMapping("/getUserPhone")
    public R getUserPhone(@RequestBody JSONObject inData) {
        try {
            String sessionKey = inData.getString("sessionKey");
            String signature = inData.getString("signature");
            String rawData = inData.getString("rawData");
            String encryptedData = inData.getString("encryptedData");
            String iv = inData.getString("iv");
            // 用户信息校验
            if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
                return R.error("获取用户信息接口出错");
            }
            // 解密用户信息
            WxMaPhoneNumberInfo wxMaPhoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
            return R.data(wxMaPhoneNumberInfo);
        } catch (Exception e) {
            log.error("调用微信服务器出现异常", e);
            return R.error("调用微信服务器出现异常");
        }

    }
}